﻿
namespace n_CLineList
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;

using n_MyObject;
using n_MyFileObject;
using n_Shape;
using n_GUIset;
using n_EventIns;
using n_HardModule;
using n_Common;
using n_GUIcoder;
using n_ImagePanel;
using n_CCEngine;

//*****************************************************
//电路线记录器
public class CLineList
{
	public ImagePanel Owner;
	
	public CPort[][] CL_List;
	public int Length;
	
	const int MaxNumber = 2;
	
	int LastX;
	int LastY;
	
	const int R = 6;
	const int R2 = R * 2;
	const int RN = 15;
	
	bool ExistMouseNear;
	public CPort MouseOnMidPort;
	
	//------------
	
	static Pen LinePenSim;
	static Pen LinePenSim0;
	static Pen LinePenSim1;
	static Pen LinePen0;
	static Pen LinePen1;
	static Pen LinePenOn;
	static Pen LinePenIndex;
	
	static Brush PortMapBrush;
	
	public static int ShowMesTick;
	
	//------------
	
	const int MaxNetNumber = 2000;
	CNetNode[] NetList;
	int NetListLength;
	
	public bool ExistPress;
	public bool NotAddList;
	
	public bool Exist;
	int CC_ID;
	
	int MouseX;
	int MouseY;
	
	//------------
	
	//虚拟机内存
	public static byte[] BASE;
	
	//------------
	
	//初始化
	public static void Init()
	{
		LinePenSim = new Pen( Color.SlateGray, 2 );
		LinePenSim.StartCap = LineCap.Round;
		LinePenSim.EndCap = LineCap.Round;
		
		LinePenSim0 = new Pen( Color.White, 2 );
		LinePenSim0.StartCap = LineCap.Round;
		LinePenSim0.EndCap = LineCap.Round;
		LinePenSim0.DashStyle = DashStyle.Dash;
		LinePenSim0.DashPattern = new float[]{15,1}; //{8,10};
		LinePenSim0.DashOffset = 0;
		
		//数字量导线, 目前用不到
		LinePenSim1 = new Pen( Color.SlateGray, 2 );
		LinePenSim1.StartCap = LineCap.Round;
		LinePenSim1.EndCap = LineCap.Round;
		LinePenSim1.DashStyle = DashStyle.Dash;
		LinePenSim1.DashPattern = new float[]{20,1};
		LinePenSim1.DashOffset = 0;
		
		LinePen0 = new Pen( Color.SlateGray, 2 );
		LinePen1 = new Pen( Color.Black, 1 );
		
		LinePen0.StartCap = LineCap.Round;
		LinePen0.EndCap = LineCap.Round;
		
		LinePen1.StartCap = LineCap.Round;
		LinePen1.EndCap = LineCap.Round;
		
		LinePenOn = new Pen( Color.Yellow, 5 );
		LinePenIndex = new Pen( Color.SlateGray, 10 );
		
		PortMapBrush = new SolidBrush( Color.FromArgb( 100, Color.CornflowerBlue ) );
		
		ShowMesTick = 0;
	}
	
	//构造函数
	public CLineList( ImagePanel m )
	{
		Owner = m;
		
		CL_List = new CPort[1000][];
		Length = 0;
		
		ExistMouseNear = false;
		MouseOnMidPort = null;
		
		NetList = new CNetNode[MaxNetNumber];
	}
	
	//显示调试信息
	void SetDebug()
	{
		string Message = "";
		Message += "L:" + NetListLength + "\n";
		for( int j = 0; j < NetListLength; ++j ) {
			Message += j + ": " + NetList[j].Show() + "\n";
		}
		Message += "\nF:\n";
		for( int j = 0; j < NetListLength; ++j ) {
			Message += j + ": " + NetList[j].ShowF() + "\n";
		}
	}
	
	//------------------------------------------------------------
	
	//计算运行网络
	public string GetNet()
	{
		string NullRun = "unit SYS_CTCOM { uint8 ElmList; void Run() {} }\n";
		
		if( G.CGPanel == null ) {
			return NullRun;
		}
		DeleteRepeatPort();
		
		Exist = GetCrossOK();
		if( !Exist ) {
			return NullRun;
		}
		
		//记录所有模块的端口
		NetListLength = 0;
		foreach( MyObject mo in G.CGPanel.myModuleList ) {
			if( !(mo is HardModule) ) {
				continue;
			}
			HardModule mm = (HardModule)mo;
			if( !mm.isCircuit ) {
				continue;
			}
			//处理端口
			for( int i = 0; i < mm.PORTList.Length; ++i ) {
				Port p = mm.PORTList[i];
				
				if( p.FuncName != n_GUIcoder.PortFuncName.C_Analog && p.FuncName != n_GUIcoder.PortFuncName.C_Digital ) {
					continue;
				}
				int x = Common.GetCrossValue( mm.MidX + p.X );
				int y = Common.GetCrossValue( mm.MidY + p.Y );
				
				AddObject( p, x, y );
			}
		}
		//添加所有线段的端口
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			for( int j = 0; j < MaxNumber; ++j ) {
				
				CPort cp = CL_List[i][j];
				AddObject( cp, cp.X, cp.Y );
				
				cp.NetIndex = -1;
				cp.TempNetIndex = -1;
			}
		}
		//复制
		for( int j = 0; j < NetListLength; ++j ) {
			NetList[j].CopyList();
		}
		//标记每个线段的目标端口
		for( int j = 0; j < NetListLength; ++j ) {
			for( int i = 0; i < NetList[j].PinNumber; ++i ) {
				object pin = NetList[j].PinList[i];
				if( pin is CPort ) {
					CPort pp = (CPort)pin;
					pp.NetIndex = j;
					pp.TempNetIndex = j;
				}
			}
		}
		//遍历导线, 合并同电位的所有端口
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			CPort cp0 = CL_List[i][0];
			CPort cp1 = CL_List[i][1];
			if( cp0.TempNetIndex == -1 || cp1.TempNetIndex == -1 || cp0.TempNetIndex == cp1.TempNetIndex ) {
				continue;
			}
			NetList[cp0.TempNetIndex].AddNet( NetList[cp1.TempNetIndex] );
		}
		
		
		/*
		//显示
		n_Debug.Debug.Message = "";
		n_Debug.Debug.Message += "L:" + NetListLength + "\n";
		for( int j = 0; j < NetListLength; ++j ) {
			n_Debug.Debug.Message += j + ": " + NetList[j].Show() + "\n";
		}
		n_Debug.Debug.Message += "\nF:\n";
		for( int j = 0; j < NetListLength; ++j ) {
			n_Debug.Debug.Message += j + ": " + NetList[j].ShowF() + "\n";
		}
		*/
		
		
		return GetAnalogCode();// + GetDigitalCode();
	}
	
	//更新交点网格
	public bool GetCrossOK()
	{
		bool Exist = false;
		CC_ID = 0;
		
		//记录所有模块的端口
		NetListLength = 0;
		foreach( MyObject mo in Owner.myModuleList ) {
			if( !(mo is HardModule) ) {
				continue;
			}
			HardModule mm = (HardModule)mo;
			if( !mm.isCircuit ) {
				continue;
			}
			mm.CC_ID = CC_ID;
			CC_ID++;
			
			//处理端口
			for( int i = 0; i < mm.PORTList.Length; ++i ) {
				Port p = mm.PORTList[i];
				
				if( p.FuncName != n_GUIcoder.PortFuncName.C_Analog && p.FuncName != n_GUIcoder.PortFuncName.C_Digital ) {
					continue;
				}
				Exist = true;
				
				int x = Common.GetCrossValue( mm.MidX + p.X );
				int y = Common.GetCrossValue( mm.MidY + p.Y );
				
				AddObject( p, x, y );
			}
		}
		if( !Exist ) {
			return false;
		}
		//添加所有线段的端口
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			for( int j = 0; j < MaxNumber; ++j ) {
				
				CPort cp = CL_List[i][j];
				AddObject( cp, cp.X, cp.Y );
				
				cp.NetIndex = -1;
				cp.TempNetIndex = -1;
			}
		}
		return true;
	}
	
	//删除重复导线
	public void DeleteRepeatPort()
	{
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			CPort cpi0 = CL_List[i][0];
			CPort cpi1 = CL_List[i][1];
			
			for( int j = 0; j < Length; ++j ) {
				if( CL_List[j] == null ) {
					continue;
				}
				
				if( i == j ) {
					continue;
				}
				CPort cpj0 = CL_List[j][0];
				CPort cpj1 = CL_List[j][1];
				
				if( cpi0.X == cpj0.X && cpi0.Y == cpj0.Y && cpi1.X == cpj1.X && cpi1.Y == cpj1.Y ||
					cpi0.X == cpj1.X && cpi0.Y == cpj1.Y && cpi1.X == cpj0.X && cpi1.Y == cpj0.Y ) {
					Delete( j );
				}
			}
		}
	}
	
	//获取Analog代码
	string GetAnalogCode()
	{
		string r = "";
		string C_V = "";
		string C_Init = "";
		
		string COM_C_V = "";
		
		foreach( MyObject mo in G.CGPanel.myModuleList ) {
			if( !(mo is HardModule) ) {
				continue;
			}
			HardModule mm = (HardModule)mo;
			if( !mm.isAnalog ) {
				continue;
			}
			C_V += "\t" + mm.Name + ".driver.C_V();\n";
			C_Init += "\t#.SYS_CTCOM.ElmList[" + mm.CC_ID + "][0] = " + (int)mm.CC_Type + ".0;\n";
		}
		int nodenumer = 0;
		for( int j = 0; j < NetListLength; ++j ) {
			
			if( NetList[j].F_PinNumber == 0 ) {
				continue;
			}
			int n = 0;
			string func_v = "";
			for( int i = 0; i < NetList[j].F_PinNumber; ++i ) {
				object pin = NetList[j].F_PinList[i];
				if( pin is Port && ((Port)pin).Owner.isAnalog ) {
					Port pp = (Port)pin;
					func_v += pp.Owner.CC_ID + "," + pp.Name + ", ";
					n++;
				}
			}
			if( n == 0 ) {
				//....
			}
			else if( n == 1 ) {
				//COM_C_I += clear_i;
			}
			else {
				COM_C_V += "\t" + n + ", " + func_v + "\n";
				nodenumer++;
			}
		}
		r += "const uint16 C_ELength = " + CC_ID + ";\n";
		r += "#.SYS_CTCOM.ELength = C_ELength;\n";
		r += "void C_Init()\n{\n" + C_Init + "}\n";
		//r += "void C_Run0()\n{\n" + C_V + "}\n";
		r += "[]#.code uint8 CN_LIST =\n[\n\t" + nodenumer + ",\n" + COM_C_V + "];\n";
		r += "SYS_CTCOM.NodeList = CN_LIST;\n";
		r += "public SYS_CTCOM =\n" + "#include <circuit\\COM.txt>\n";
		r += CCEngine.GetROM_Code();
		return r;
		
		
		////r = "void C_Run0()\n{\n" + C_V + "\tloop (10) {\n" + COM_C_V + "\n\t}\n" + C_I + "\tloop (10) {\n" + COM_C_I + "\n\t}\n" + C_R + "}\n";
		//r = "void C_Run0()\n{\n" + C_V + COM_C_V + C_I + COM_C_I + C_R + "}\n";
		//return r + "void C_Run()\n{\n" + C_S + "\tloop(50) {\n\t\tC_Run0();\n\t}\n" + C_T + "}\n" +
		//	"public COM =\n" + "#include <circuit\\COM.txt>\n";
	}
	
	//获取Digital代码
	string GetDigitalCode()
	{
		/*
		//清空所有端口的处理标志
		foreach( MyObject mo in G.CGPanel.myModuleList ) {
			if( !(mo is HardModule) ) {
				continue;
			}
			HardModule mm = (HardModule)mo;
			if( !mm.isDigital ) {
				continue;
			}
			mm.D_OK = false;
			for( int i = 0; i < mm.PORTList.Length; ++i ) {
				mm.PORTList[i].D_OK = false;
			}
		}
		*/
		
		//遍历迭代提取就绪的模块生成代码
		string r = "void CD_Run()\n{\n";
		string trans = "";
		
		foreach( MyObject mo in G.CGPanel.myModuleList ) {
			if( !(mo is HardModule) ) {
				continue;
			}
			HardModule mm = (HardModule)mo;
			if( !mm.isDigital ) {
				continue;
			}
			
			r += "\t" + mm.Name + ".driver.Deal();\n";
			
			//这里根据Port设置关联的所有模块Port, 并生成Port位传递函数
			for( int i = 0; i < mm.PORTList.Length; ++i ) {
				if( mm.PORTList[i].ClientType != n_GUIcoder.PortClientType.MASTER ) {
					continue;
				}
				//根据当前端口设置关联的其他端口就绪状态
				int j = mm.PORTList[i].Net_Index;
				for( int n = 0; n < NetList[j].F_PinNumber; ++n ) {
					object pin = NetList[j].F_PinList[n];
					if( pin == mm.PORTList[i] ) {
						continue;
					}
					if( pin is Port && ((Port)pin).Owner.isDigital ) {
						Port pp = (Port)pin;
						
						trans += "\t" + pp.Owner.Name + ".driver.Input." + pp.Name + "(bit) = " + mm.PORTList[i].Owner.Name + ".driver.Output." + mm.PORTList[i].Name.Remove( 0, 1 ) + "(bit);" + "\n";
					}
				}
			}
		}
		r += trans;
		r += "\n}\n";
		
		return r;
	}
	
	//添加新的端口
	void AddObject( object o, int x, int y )
	{
		bool noadd = true;
		for( int j = 0; j < NetListLength; ++j ) {
			if( NetList[j].X == x && NetList[j].Y == y ) {
				NetList[j].AddObject( o );
				noadd = false;
				break;
			}
		}
		if( noadd ) {
			CNetNode cn = new CNetNode( NetListLength );
			cn.AddObject( o );
			cn.SetPoint( x, y );
			NetList[NetListLength] = cn;
			NetListLength++;
		}
	}
	
	//------------------------------------------------------------
	
	//仿真复位
	public void ResetSim()
	{
		int vidx = n_VarList.VarList.GetStaticIndex( "#.SYS_CTCOM.ElmList" );
		string viaddr = n_VarList.VarList.GetAddr( vidx );
		int VI_Addr = int.Parse( viaddr );
		
		for( int j = 0; j < NetListLength; ++j ) {
			
			for( int i = 0; i < NetList[j].PinNumber; ++i ) {
				object pin = NetList[j].PinList[i];
				if( pin is Port ) {
					Port pp = (Port)pin;
					if( pp.Owner.isAnalog ) {
						int ppindex = int.Parse( pp.Name );
						pp.I_Addr = VI_Addr + (pp.Owner.CC_ID*CCEngine.VNumber + CCEngine.ECVI + (ppindex-1)*2)*4;
						pp.V_Addr = pp.I_Addr + 4;
					}
					if( pp.Owner.isDigital ) {
						if( pp.ClientType == PortClientType.CLIENT ) {
							int idx = n_VarList.VarList.GetStaticIndex( "#." + pp.Owner.Name + ".driver.Input" );
							string addr = n_VarList.VarList.GetAddr( idx );
							pp.Input_Addr = int.Parse( addr );
							pp.C_Index = int.Parse( pp.Name );
						}
						else {
							int idx = n_VarList.VarList.GetStaticIndex( "#." + pp.Owner.Name + ".driver.Output" );
							string addr = n_VarList.VarList.GetAddr( idx );
							pp.Output_Addr = int.Parse( addr );
							pp.C_Index = int.Parse( pp.Name.Remove( 0, 1 ) );
						}
					}
				}
			}
		}
	}
	
	//------------------------------------------------------------
	
	//设置为鼠标按下状态
	public void SetMoveStatus( int x, int y )
	{
		x = Common.GetCrossValue( x );
		y = Common.GetCrossValue( y );
		
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			for( int j = 0; j < MaxNumber; ++j ) {
				
				if( CL_List[i][j].X == x && CL_List[i][j].Y == y ) {
					CL_List[i][j].isMove = true;
					
					CL_List[i][j].mov_x = CL_List[i][j].X;
					CL_List[i][j].mov_y = CL_List[i][j].Y;
					
					break;
				}
			}
		}
	}
	
	//自动移动
	public void AutoMove( int x, int y )
	{
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			for( int j = 0; j < MaxNumber; ++j ) {
				
				if( CL_List[i][j].isMove ) {
					CL_List[i][j].X = CL_List[i][j].mov_x + x;
					CL_List[i][j].Y = CL_List[i][j].mov_y + y;
				}
			}
		}
	}
	
	//显示
	public void Draw( Graphics g )
	{
		if( G.SimulateMode ) {
			bool ok = true;
			int tick = 0;
			do {
				tick++;
				ok = true;
				for( int j = 0; j < NetListLength; ++j ) {
					CPort cpi = null;
					CPort cpv = null;
					bool single = true;
					int I = 0;
					int V = 0;
					int Vn = 0;
					int In = 0;
					bool isDigital = false;
					bool isHigh = false;
					for( int i = 0; i < NetList[j].PinNumber; ++i ) {
						object pin = NetList[j].PinList[i];
						if( pin is Port ) {
							Port pp = (Port)pin;
							int I_addr = pp.I_Addr;
							long idata = n_Data.Data.GetInt32( BASE, I_addr );
							I += (int)idata;
							int V_addr = pp.V_Addr;
							long vdata = n_Data.Data.GetInt32( BASE, V_addr );
							V += (int)vdata;
							Vn++;
							In++;
						}
						else {
							CPort c = (CPort)pin;
							if( c.VOK ) {
								V += c.V;
								Vn++;
							}
							else {
								cpv = c;
							}
							if( c.IOK ) {
								I += c.I;
								In++;
								isDigital |= c.isDigital;
								isHigh |= c.isHigh;
							}
							else {
								if( cpi != null ) {
									single = false;
								}
								else {
									cpi = c;
								}
							}
						}
					}
					if( cpv != null && !cpv.VOK && Vn != 0 ) {
						
						int iidx = 0;
						if( cpv.iidx == 0 ) {
							iidx = 1;
						}
						cpv.VOK = true;
						cpv.V = V/Vn;
						CL_List[cpv.Index][iidx].VOK = true;
						CL_List[cpv.Index][iidx].V = V/Vn;
						ok = false;
					}
					if( cpi != null && single ) {
						int iidx = 0;
						if( cpi.iidx == 0 ) {
							iidx = 1;
						}
						cpi.IOK = true;
						cpi.isDigital = isDigital;
						cpi.I = -I;
						cpi.isHigh = isHigh;
						
						CL_List[cpi.Index][iidx].IOK = true;
						CL_List[cpi.Index][iidx].isDigital = isDigital;
						CL_List[cpi.Index][iidx].I = I;
						CL_List[cpi.Index][iidx].isHigh = isHigh;
						ok = false;
					}
				}
			}
			while( !ok );
		}
		
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			if( G.SimulateMode ) {
				
				float ri = CL_List[i][0].I / 10.0f;
				int r = CL_List[i][0].V / 20000;
				if( CL_List[i][0].isDigital ) {
					if( r >= 0 ) {
						r = 250;
					}
					else {
						r = -250;
					}
				}
				
				CL_List[i][0].Offset += ri;
				
				bool isNeg = r < 0;
				r = Math.Abs( r );
				
				//非线性映射
				//if( r > 300 ) {
				//	r = 300;
				//}
				//r = (255*r) / (70 + r);
				
				//标准映射
				if( r > 255 ) {
					r = 255;
				}
				
				//灰度补偿映射
				//if( r > 300 ) {
				//	r = 300;
				//}
				
				/*
				//非线性映射
				r = (250*r) / (50 + r);
				//r = r * 200 / 300;
				int bl = r;
				r += 55;
				if( r > 255 ) {
					r = 255;
				}
				*/
				
				int d_r = 255 - r;
				
				/*
				int rr = 0;
				int gg = 0;
				if( r >= 128 ) {
					rr = 255;
					gg = (255-r) * 2;
				}
				else {
					gg = 255;
					rr = r*2;
				}
				*/
				
				//g.DrawLine( Pens.SlateGray, CL_List[i][0].X, CL_List[i][0].Y, CL_List[i][1].X, CL_List[i][1].Y );
				
				if( CL_List[i][0].isDigital ) {
					if( CL_List[i][0].isHigh ) {
						LinePenSim1.Color = Color.FromArgb( 255, d_r, d_r );
					}
					else {
						LinePenSim1.Color = Color.FromArgb( d_r, d_r, 255 );
					}
					LinePenSim1.DashOffset = (int)(CL_List[i][0].Offset / 2000); //1000
					g.DrawLine( LinePenSim1, CL_List[i][0].X, CL_List[i][0].Y, CL_List[i][1].X, CL_List[i][1].Y );
				}
				else {
					//LinePenSim.Color = Color.FromArgb( r, 0, 0 );
					//g.DrawLine( LinePenSim, CL_List[i][0].X, CL_List[i][0].Y, CL_List[i][1].X, CL_List[i][1].Y );
					
					int ot = 0;//(200-bl) * 50 / 200;
					if( ot < 0 ) ot = 0;
					
					if( isNeg ) {
						LinePenSim0.Color = Color.FromArgb( ot, r, ot );
					}
					else {
						LinePenSim0.Color = Color.FromArgb( r, ot, ot );
					}
					
					LinePenSim0.DashOffset = (int)(CL_List[i][0].Offset / 300);
					g.DrawLine( LinePenSim0, CL_List[i][0].X, CL_List[i][0].Y, CL_List[i][1].X, CL_List[i][1].Y );
				}
			}
			else {
				g.DrawLine( LinePen0, CL_List[i][1].X, CL_List[i][1].Y, CL_List[i][0].X, CL_List[i][0].Y );
			}
		}
		
		//绘制所有导线
		bool HasShowPortMes = false;
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			if( !G.SimulateMode ) {
				if( i == G.CGPanel.CLineIndex ) {
					g.DrawLine( LinePenOn, CL_List[i][0].X, CL_List[i][0].Y, CL_List[i][1].X, CL_List[i][1].Y );
				}
				else {
					g.DrawLine( LinePen1, CL_List[i][0].X, CL_List[i][0].Y, CL_List[i][1].X, CL_List[i][1].Y );
				}
			}
			//判断是否有重叠的导线
			if( CL_List[i][0].X == CL_List[i][1].X && CL_List[i][0].Y == CL_List[i][1].Y ) {
				float midx = CL_List[i][0].X;
				float midy = CL_List[i][0].Y;
				
				g.DrawEllipse( Pens.OrangeRed, midx - R2, midy - R2, R2*2, R2*2 );
				g.DrawString( "注意: 导线长度为0, 请拖动分开 (起点和终点重合)", GUIset.Font11, Brushes.OrangeRed, CL_List[i][0].X + 15, CL_List[i][0].Y - 12 );
			}
			
			for( int j = 0; j < MaxNumber; ++j ) {
				
				if( CL_List[i][j].MouseOn ) {
					float midx = CL_List[i][j].X;
					float midy = CL_List[i][j].Y;
					g.DrawLine( Pens.DarkGray, midx - 1000, midy, midx + 1000, midy );
					g.DrawLine( Pens.DarkGray, midx, midy - 1000, midx, midy + 1000 );
				}
				if( CL_List[i][j].MousePress ) {
					float midx = CL_List[i][j].X;
					float midy = CL_List[i][j].Y;
					g.DrawLine( Pens.Orange, midx - 1000, midy, midx + 1000, midy );
					g.DrawLine( Pens.Orange, midx, midy - 1000, midx, midy + 1000 );
				}
				
				
				
				
				/*
				if( !CL_List[i][j].isHigh ) {
					float midx = CL_List[i][j].X;
					float midy = CL_List[i][j].Y;
					g.DrawEllipse( Pens.Red, midx - R, midy - R, R2, R2 );
				}
				*/
				/*
				if( CL_List[i][j].isDigital ) {
					float midx = CL_List[i][j].X;
					float midy = CL_List[i][j].Y;
					if( CL_List[i][j].I > 0 ) {
						g.DrawEllipse( Pens.Green, midx - R, midy - R, R2, R2 );
					}
					else {
						g.DrawEllipse( Pens.Red, midx - R, midy - R, R2, R2 );
					}
				}
				*/
				
				
				
				CL_List[i][j].isDigital = false;
				CL_List[i][j].IOK = false;
				CL_List[i][j].VOK = false;
				
				//显示端口序号
				//g.DrawString( i + "-" + j + ": ", GUIset.Font11, Brushes.Black, CL_List[i][j].X - 15, CL_List[i][j].Y + 10 );
				
				//仿真模式下不需要显示线段端口
				if( G.SimulateMode ) {
					continue;
				}
				if( ExistMouseNear ) {
					float midx = CL_List[i][j].X;
					float midy = CL_List[i][j].Y;
					//g.DrawEllipse( Pens.DarkSlateGray, midx - R, midy - R, R2, R2 );
				}
				
				if( CL_List[i][j].MouseOn ) {
					float midx = CL_List[i][j].X;
					float midy = CL_List[i][j].Y;
					g.FillEllipse( Brushes.Orange, midx - R, midy - R, R2, R2 );
					g.DrawEllipse( Pens.Red, midx - R, midy - R, R2, R2 );
					
					if( !HasShowPortMes && ShowMesTick == 0 && !G.SimulateMode ) {
						HasShowPortMes = true;
						
						g.FillRectangle( PortMapBrush, midx - 110, midy - 40, 220, 30 );
						g.DrawRectangle( Pens.DimGray, midx - 110, midy - 40, 220, 30 );
						g.DrawString( "点击右键可删除此拖点及相连导线", GUIset.ModuleNameFont, Brushes.Black, midx + 5 - 107, midy + 5 - 40 );
					}
				}
				else if( CL_List[i][j].MouseNear ) {
					float midx = CL_List[i][j].X;
					float midy = CL_List[i][j].Y;
					g.FillEllipse( Brushes.LightSlateGray, midx - R, midy - R, R2, R2 );
					g.DrawEllipse( Pens.DarkSlateGray, midx - R, midy - R, R2, R2 );
				}
				else {
					//...
				}
			}
			//n_Debug.Debug.Message += i + ":" + " " + CL_List[i][0].X + ", " + CL_List[i][0].Y + "   ";
			//n_Debug.Debug.Message += CL_List[i][1].X + ", " + CL_List[i][1].Y + "\n";
		}
		
		//绘制每个交点圆圈
		for( int j = 0; j < NetListLength; ++j ) {
			if( NetList[j].PinNumber >= 3 ) {
				int xx = 0;
				int yy = 0;
				object pin = NetList[j].PinList[0];
				if( pin is CPort ) {
					CPort pp = (CPort)pin;
					xx = pp.X;
					yy = pp.Y;
				}
				else {
					Port p = (Port)pin;
					xx = Common.GetCrossValue( p.Owner.MidX + p.X );
					yy = Common.GetCrossValue( p.Owner.MidY + p.Y );
				}
				
				g.FillEllipse( Brushes.SlateGray, xx - 4, yy - 4, 8, 8 );
				
				if( G.SimulateMode ) {
					g.FillEllipse( Brushes.Black, xx - 3, yy - 3, 6, 6 );
				}
				else {
					g.FillEllipse( Brushes.Black, xx - 3, yy - 3, 6, 6 );
				}
			}
		}
		//显示电流和电压
		if( G.SimulateMode && G.CGPanel.CLineIndex != -1 ) {
			
			int i = G.CGPanel.CLineIndex;
			
			//计算电流
			float fi = Math.Abs( CL_List[i][0].I );
			fi /= 1024;
			
			//计算电压
			float fv = CL_List[i][0].V;
			fv /= 1024;
			
			int uix = (CL_List[i][0].X+CL_List[i][1].X)/2 + 5;
			int uiy = (CL_List[i][0].Y+CL_List[i][1].Y)/2 + 5;
			uix = MouseX - 48;
			uiy = MouseY - 48;
			g.DrawLine( Pens.Yellow, CL_List[i][0].X, CL_List[i][0].Y, CL_List[i][1].X, CL_List[i][1].Y );
			
			g.FillRectangle( Brushes.Gainsboro, uix, uiy, 96, 38 );
			g.DrawRectangle( Pens.SlateGray, uix, uiy, 96, 38 );
			g.DrawString( fi.ToString( "f2" ), GUIset.Font11, Brushes.Blue, uix, uiy );
			g.DrawString( "mA", GUIset.Font11, Brushes.SlateGray, uix + 66, uiy );
			g.DrawString( fv.ToString( "f2" ), GUIset.Font11, Brushes.Red, uix, uiy + 20 );
			g.DrawString( "mV", GUIset.Font11, Brushes.SlateGray, uix + 66, uiy + 20 );
			//g.DrawString( fi.ToString(  ) + "mA\n" + fv.ToString(  ) + "mV", GUIset.Font11, Brushes.Black, uix, uiy );
		}
	}
	
	//显示
	public void DrawIndex( Graphics g )
	{
		//绘制所有导线
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			LinePenIndex.Color = Color.FromArgb( i%256, i/256, 16 );
			g.DrawLine( LinePenIndex, CL_List[i][0].X, CL_List[i][0].Y, CL_List[i][1].X, CL_List[i][1].Y );
		}
	}
	
	//鼠标移动事件
	public void MouseMove( int mX, int mY )
	{
		MouseX = mX;
		MouseY = mY;
		
		ExistMouseNear = false;
		MouseOnMidPort = null;
		ExistPress = false;
		
		/*
		放到鼠标松开事件了
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			for( int j = 0; j < MaxNumber; ++j ) {
				CL_List[i][j].isNew = false;
			}
		}
		*/
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			for( int j = 0; j < MaxNumber; ++j ) {
				
				ExistPress |= CL_List[i][j].MousePress;
				
				if( CL_List[i][j].MousePress && G.CGPanel.CLineIndex != -1 ) {
					
					if( CL_List[G.CGPanel.CLineIndex][0] == CL_List[i][j] || CL_List[G.CGPanel.CLineIndex][1] == CL_List[i][j] ) {
						G.CGPanel.CLineIndex = -1;
					}
				}
				if( CL_List[i][j].MousePress && !CL_List[i][j].isMove ) {
					ExistMouseNear = true;
					
					//PortList[i][j].X += mX - LastX;
					//PortList[i][j].Y += mY - LastY;
					
					CL_List[i][j].X = mX;
					CL_List[i][j].Y = mY;
					
					CL_List[i][j].X = n_Common.Common.GetCrossValue( mX );
					CL_List[i][j].Y = n_Common.Common.GetCrossValue( mY );
					
					if( CL_List[i][j].mov_x != CL_List[i][j].X || CL_List[i][j].mov_y != CL_List[i][j].Y ) {
						CL_List[i][j].Click = false;
					}
					ShowMesTick++;
				}
				else {
					float midx = CL_List[i][j].X;
					float midy = CL_List[i][j].Y;
					if( mX >= midx - R && mX <= midx + R && mY >= midy - R && mY <= midy + R ) {
						CL_List[i][j].MouseOn = true;
						ExistMouseNear = true;
						
						MouseOnMidPort = CL_List[i][j];
						
						G.CGPanel.CLineIndex = -1;
					}
					else {
						CL_List[i][j].MouseOn = false;
					}
					if( mX >= midx - R - RN && mX <= midx + R + RN && mY >= midy - R - RN && mY <= midy + R + RN ) {
						CL_List[i][j].MouseNear = true;
						ExistMouseNear = true;
					}
					else {
						CL_List[i][j].MouseNear = false;
					}
				}
			}
		}
		//LastX = mX;
		//LastY = mY;
	}
	
	//鼠标左键按下事件
	public bool LeftMouseDown( int mX, int mY )
	{
		LastX = mX;
		LastY = mY;
		
		if( G.CGPanel.CLineIndex != -1 ) {
			return false;
		}
		
		bool Press = false;
		for( int i = Length - 1; i >= 0; --i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			for( int j = MaxNumber - 1; j >= 0; --j ) {
				
				CL_List[i][j].isNew = false;
				if( CL_List[i][j].MouseOn ) {
					CL_List[i][j].MousePress = true;
					CL_List[i][j].Click = true;
					
					CL_List[i][j].mov_x = CL_List[i][j].X;
					CL_List[i][j].mov_y = CL_List[i][j].Y;
					
					Press = true;
					break;
				}
			}
		}
		return Press;
	}
	
	//鼠标左键松开事件
	public void LeftMouseUp( int mX, int mY )
	{
		bool HasAddClick = NotAddList;
		CPort addnew = null;
		
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			for( int j = 0; j < MaxNumber; ++j ) {
				
				if( ExistPress && CL_List[i][j].MousePress && CL_List[i][j] != addnew && addnew != null ) {
					addnew = null;
				}
				
				CL_List[i][j].isMove = false;
				
				//注意这里, 随后的迭代中有可能处理到AddList新加的节点, 不能清掉他们的Press标志, 所以判断一下
				if( !CL_List[i][j].isNew ) {
					CL_List[i][j].MousePress = false;
				}
				if( CL_List[i][j].Click ) {
					CL_List[i][j].Click = false;
					
					if( !HasAddClick ) {
						HasAddClick = true;
						
						addnew = CL_List[i][j];
					}
				}
				if( G.CGPanel.CLineIndex != -1 ) {
					CL_List[i][j].MousePress = false;
				}
			}
		}
		if( !G.SimulateMode ) {
			//判断是否要分割导线
			int gcindex = G.CGPanel.CLineIndex;
			if( gcindex != -1 ) {
				AddList( false, CL_List[gcindex][0].X, CL_List[gcindex][0].Y, Common.GetCrossValue( mX ), Common.GetCrossValue( mY ) );
				AddList( false, CL_List[gcindex][1].X, CL_List[gcindex][1].Y, Common.GetCrossValue( mX ), Common.GetCrossValue( mY ) );
				Delete( gcindex );
			}
			else {
				if( addnew != null ) {
					AddList( true, addnew.X, addnew.Y, addnew.X, addnew.Y );
				}
			}
			//更新网络
			//if( needRefresh ) {
			bool e = GetCrossOK();
			//}
		}
		
		NotAddList = false;
	}
	
	//鼠标右键按下事件
	public bool RightMouseDown( int mX, int mY )
	{
		if( G.SimulateMode ) {
			return false;
		}
		for( int i = Length - 1; i >= 0; --i ) {
			if( CL_List[i] == null ) {
				continue;
			}
			for( int j = MaxNumber - 1; j >= 0; --j ) {
				if( CL_List[i][j].MouseOn ) {
					
					Delete( CL_List[i][j].Index );
					G.CGPanel.CLineIndex = -1;
					
					//更新网络
					bool e = GetCrossOK();
					
					G.CGPanel.myModuleList.NeedDrawLineMap = true;
					break;
				}
			}
		}
		return false;
	}
	
	//添加新的节点系列
	public int AddList( bool Press, int xx, int yy, int xx1, int yy1 )
	{
		int x = Common.GetCrossValue( xx );
		int y = Common.GetCrossValue( yy );
		int x1 = Common.GetCrossValue( xx1 );
		int y1 = Common.GetCrossValue( yy1 );
		
		int ii = Length;
		for( int i = 0; i < Length; ++i ) {
			if( CL_List[i] == null ) {
				ii = i;
				break;
			}
		}
		CL_List[ii] = new CPort[MaxNumber];
		CL_List[ii][0] = new CPort( ii, 0, x, y );
		CL_List[ii][1] = new CPort( ii, 1, x1, y1 );
		
		CL_List[ii][0].MousePress = Press;
		CL_List[ii][0].MouseOn = Press;
		CL_List[ii][0].MouseNear = Press;
		
		if( Length <= ii ) {
			Length = ii + 1;
		}
		return ii;
	}
	
	//清空节点列表
	public void Delete( int index )
	{
		CL_List[index] = null;
	}
}
//===================================================================
//过渡点链接节点
public class CPort
{
	public int X;
	public int Y;
	
	public int mov_x;
	public int mov_y;
	
	public bool MouseNear;
	public bool MouseOn;
	public bool MousePress;
	public bool Click;
	
	public int Index;
	public int iidx;
	
	public bool isNew;
	public bool isMove;
	
	public int NetIndex;
	public int TempNetIndex;
	
	//----------------------------
	
	public int I;
	public int V;
	public bool IOK;
	public bool VOK;
	public float Offset;
	public bool isDigital;
	public bool isHigh;
	
	//构造函数
	public CPort( int i, int j, int x, int y )
	{
		MouseNear = false;
		MouseOn = false;
		MousePress = false;
		Click = false;
		isMove = false;
		
		X = x;
		Y = y;
		
		Index = i;
		iidx = j;
		
		isNew = true;
		
		NetIndex = -1;
		TempNetIndex = -1;
		IOK = false;
		VOK = false;
		isDigital = false;
	}
}
//===================================================================
//网络图节点 - 包括一个坐标列表和一个目标端口列表
public class CNetNode
{
	public int Index;
	
	//最大节点相交数目
	const int MaxCrossNumber = 500;
	
	//public Point[] PointList;
	//public int PointNumber;
	
	public int X;
	public int Y;
	
	public object[] PinList;
	public int PinNumber;
	
	public object[] F_PinList;
	public int F_PinNumber;
	
	//构造函数
	public CNetNode( int i )
	{
		Index = i;
		
		PinList = new object[MaxCrossNumber];
		PinNumber = 0;
		
		F_PinList = new object[MaxCrossNumber];
		F_PinNumber = 0;
	}
	
	//复制当前的列表到最终列表
	public void CopyList()
	{
		for( int i = 0; i < PinNumber; ++i ) {
			F_PinList[i] = PinList[i];
		}
		F_PinNumber = PinNumber;
	}
	
	//添加另一个网络节点
	public void AddNet( CNetNode n )
	{
		for( int i = 0; i < n.F_PinNumber; ++i ) {
			
			F_PinList[F_PinNumber] = n.F_PinList[i];
			F_PinNumber++;
			if( n.F_PinList[i] is CPort ) {
				CPort cp = (CPort)n.F_PinList[i];
				cp.TempNetIndex = Index;
			}
			if( n.F_PinList[i] is Port ) {
				Port cp = (Port)n.F_PinList[i];
				cp.Net_Index = Index;
			}
		}
		n.F_PinNumber = 0;
	}
	
	//添加一个坐标
	public void SetPoint( int x, int y )
	{
		//PointList[PointNumber] = p;
		//PointNumber++;
		
		X = x;
		Y = y;
	}
	
	//添加一个对象
	public void AddObject( object o )
	{
		if( o is Port ) {
			Port cp = (Port)o;
			cp.Net_Index = Index;
		}
		PinList[PinNumber] = o;
		PinNumber++;
	}
	
	//显示
	public string Show()
	{
		string r = X + "," + Y + "  ";
		
		for( int i = 0; i < PinNumber; ++i ) {
			if( PinList[i] is Port ) {
				Port p = (Port)PinList[i];
				r += "P:" + p.Owner.Name + "." + p.Name + "," + p.I_Addr + "  ";
			}
			else {
				CPort cp = (CPort)PinList[i];
				r += "C:" + cp.Index + "-" + cp.iidx + "  ";
			}
		}
		return r;
	}
	
	//显示
	public string ShowF()
	{
		string r = "";
		
		for( int i = 0; i < F_PinNumber; ++i ) {
			if( F_PinList[i] is Port ) {
				Port p = (Port)F_PinList[i];
				r += "P:" + p.Owner.Name + "." + p.Name + "  ";
			}
			else {
				CPort cp = (CPort)F_PinList[i];
				r += "C:" + cp.Index + "-" + cp.iidx + "  ";
			}
		}
		return r;
	}
}
}



